package models

import (
	"SSO/tools"
	"fmt"
	"regexp"
	"time"
)

type Service struct {
	Id         int    `gorm:"AUTO_INCREMENT,primary_key" json:"id"`
	Name       string `json:"name"`
	Usn        string `json:"usn"`
	Introduce  string `json:"introduce"`
	Domain     string `json:"domain"`
	PathLogin  string `json:"path_login"`
	PathLogout string `json:"path_logout"`
	SecretKey  string `gorm:"-" json:"secret_key"`
}

type Services struct{}

func (this Services) GetAll() ([]Service, error){
	services := make([]Service, 0)
	r := tools.GetMysqlDB().Select([]string{"id", "name", "usn", "domain", "introduce", "path_logout", "path_login"}).Find(&services)
	if r.Error != nil {
		return nil, r.Error
	}
	return services, nil
}

func (this Services) GetByDomain(domain string) (*Service, error) {
	services := make([]Service, 0)
	r := tools.GetMysqlDB().Where("domain = ?", domain).Find(&services)
	if r.Error != nil {
		return nil, r.Error
	}

	if len(services) == 0 {
		return nil, nil
	}

	return &services[0], nil
}
func (this Services) GetByUsn(usn string) (*Service, error) {
	services := make([]Service, 0)
	r := tools.GetMysqlDB().Where("domain = ?", usn).Find(&services)
	if r.Error != nil {
		return nil, r.Error
	}

	if len(services) == 0 {
		return nil, nil
	}

	return &services[0], nil
}
func (Services) GetById(id int) (*Service, error) {
	services := make([]Service, 0)
	r := tools.GetMysqlDB().Where("id = ?", id).Find(&services)
	if r.Error != nil {
		return nil, r.Error
	}

	if len(services) == 0 {
		return nil, nil
	}
	return &services[0], nil
}
func (Services) GetByIds(idList []int) (services []Service, err error) {
	services = make([]Service, 0)

	r := tools.GetMysqlDB().Where("id in (?)", idList).Find(&services)

	if r.Error != nil {
		return nil, r.Error
	}

	return services, nil
}



func (this Services) CheckExistDomain(domain string) (isExist bool, err error) {
	service, err := this.GetByDomain(domain)

	if err != nil {
		fmt.Println(err)
		return
	}

	if service == nil {
		return false, nil
	}
	return true, nil
}

func (this Services) CheckName(name string) (err error){
	if name == "" {
		err =  fmt.Errorf("服务名称为空")
	}
	return
}

// 判断usn是否重复，id参数用于排除本身重复, 若不不排除可传入-1
func (this Services) CheckUsn(usn string, id int) (err error){
	if usn == "" {
		err = fmt.Errorf("usn为空")
		return
	}

	rgx := regexp.MustCompile(`^\w+$`)
	if !rgx.MatchString(usn) {
		err = fmt.Errorf("usn只能为数字、字母或下划线组成")
		return
	}

	service, err := this.GetByUsn(usn)
	if err != nil {
		return
	}

	if service != nil && service.Id != id{
		err = fmt.Errorf("usn已存在")
	}
	return
}

func (this Services) CheckDomain(domain string, id int) (err error){
	if domain == "" {
		err = fmt.Errorf("domain为空")
		return
	}

	service, err := this.GetByDomain(domain)
	if err != nil {
		return
	}

	if service != nil && service.Id != id{
		err = fmt.Errorf("domain已存在")
	}
	return
}
func (this Services) CheckPathLogin(pathLogin string) (err error){
	if pathLogin == "" {
		err = fmt.Errorf("登录路径为空")
	}
	return
}
func (this Services) CheckPathLogout(pathLogout string) (err error){
	if pathLogout == "" {
		err = fmt.Errorf("注销登录路径为空")
	}
	return

}

func (this Services) CheckInfo(id int, name, usn, domain, pathLogin, pathLogout string) (err error){
	if err = this.CheckName(name); err != nil {
		return
	}
	if err = this.CheckUsn(usn, id); err != nil {
		return
	}
	if err = this.CheckDomain(domain, id); err != nil {
		return
	}
	if err = this.CheckPathLogin(pathLogin); err != nil {
		return
	}
	if err = this.CheckPathLogout(pathLogout); err != nil {
		return
	}
	return
}

func (this Services) Create(name, usn, domain, introduce, pathLogin, pathLogout string)(int, error){
	str := fmt.Sprintf("%s:%d", usn, time.Now().UnixNano())
	secretKey := tools.Function{}.GetStrMd5(str)
	service := Service{
		Name:		name,
		Usn:		usn,
		Domain:		domain,
		Introduce:	introduce,
		PathLogout:	pathLogout,
		PathLogin:	pathLogin,
		SecretKey:	secretKey,
	}
	r := tools.GetMysqlDB().Create(&service)
	fmt.Println(service)

	if r.Error != nil {
		return -1, r.Error
	}
	return service.Id, nil
}

func (this Services) UpdateById(id int, name, usn, domain, introduce, pathLogin, pathLogout string)(error){
	service, err :=  this.GetById(id)
	if err != nil {
		return err
	}
	if service == nil {
		return fmt.Errorf("服务不存在")
	}

	service.Name		= name
	service.Usn			= usn
	service.Domain		= domain
	service.Introduce	= introduce
	service.PathLogin	= pathLogin
	service.PathLogout	= pathLogout

	r := tools.GetMysqlDB().Save(&service)

	if r.Error != nil {
		return r.Error
	}
	return nil
}

func (this Services) DeleteById(id int) error  {
	service, err :=  this.GetById(id)
	if err != nil {
		return err
	}
	if service == nil {
		return fmt.Errorf("服务不存在")
	}

	r := tools.GetMysqlDB().Delete(&service)
	if r.Error != nil {
		return r.Error
	}
	return nil
}



